﻿@page "/tablestructbatch"
@using System.Net.Http.Headers
@using System.Text
@using System.Text.RegularExpressions
@using Polly
@using Tool.Components.Pages.SmallTools
@using Tool.Models
@using Tool.Services
@inject IHttpClientFactory httpClientFactory
@inject InstanceService instanceService
@inject ISnackbar snackbar
@inject IJSRuntime javaScript
@inject IServiceProvider serviceProvider

<PageTitle>Evd</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">四极</MudText>

<MudSpacer />
<MudGrid>
	<MudItem xs="12" Class="align-content-center">
		<Login OnSuccess="HandleLogin"></Login>
	</MudItem>
	<MudItem xs="6">
		<MudTextField @bind-Value="_databases" Label="数据库名称" Variant="Variant.Text" Adornment="Adornment.Start"
					  AdornmentIcon="@Icons.Material.Filled.LockPerson" Clearable="true" Lines="12" />
	</MudItem>
	<MudItem xs="3">
		<MudTextField @bind-Value="_tableCount" Label="最大分表数量" Variant="Variant.Text" Adornment="Adornment.Start"
					  AdornmentIcon="@Icons.Material.Filled.Numbers" Clearable="true" />
	</MudItem>
	<MudItem xs="3" Class="align-content-center">
		<MudButton Class="align-self-center" FullWidth="true" Disabled="@_processing" OnClick="GetDescriptions" Variant="Variant.Filled" Color="Color.Primary">
			@if (_processing)
			{
				<ProgressBar CurrentValue="@_progress" MaxValue="@_totalCount"></ProgressBar>
				<MudText Class="ms-2">@_currentDb</MudText>
			}
			else
			{
				<MudText>获取表结构</MudText>
			}
		</MudButton>
	</MudItem>
</MudGrid>

@code {

	private string _databases = string.Empty;
	private List<string> _tables = new List<string>();
	private string _selectedInstance = "托管从库114.8";
	private string _selectedTable;
	private bool _processing = false;
	private int _tableCount = 1;
	private int _progress = 0;
	private int _totalCount = 0;
	private string _currentDb = string.Empty;

	private Regex _tableIndex = new Regex(@"(.*?)_(\d+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);


	private string _selectedSite { get; set; }

	private HttpResponseHeaders _responseHeaders { get; set; }


	protected override Task OnInitializedAsync()
	{
		base.OnInitializedAsync();

		var dbs = new List<string>
		{
			"business_approval_process_bj",
			 "conference_reimburse_bj",
			 "gwhome_abroad_reimburse_bj",
			 "gwhome_advance_bj",
			 "gwhome_base_bj",
			 "gwhome_crm_bj",
			 "gwhome_data_sync_bj",
			 "gwhome_equipment_bj",
			 "gwhome_invoice_bj",
			 "gwhome_labour_reimburse_bj",
			 "gwhome_official_document_bj",
			 "gwhome_receive_reimburse_bj",
			 "gwhome_reim_approval_bj",
			 "gwhome_reim_bj",
			 "gwhome_salary_bj",
			 "gwhome_standing_book_bj",
			 "gwhome_training_reimburse_bj",
			 "gwhome_transfer_accounts_bj",
			 "gwhome_trip_approval_bj",
			 "gwhome_trip_bj",
			 "gwhome_user_bj",
			 "medical_reimburse_bj",
			 "office_supplies_bj",
			 "payment_application_bj",
			 "yeeskygo_bj"
		};
		_databases = string.Join(Environment.NewLine, dbs);
		return Task.CompletedTask;
	}

	private async Task GetDescriptions()
	{
		try
		{
			if (string.IsNullOrWhiteSpace(_databases))
			{
				snackbar.Add("请输入数据库", Severity.Warning);
				return;
			}

			_processing = true;
			_progress = 0;

			var dbs = _databases.Split(Environment.NewLine);
			var pipeline = serviceProvider.GetRequiredKeyedService<ResiliencePipeline>("my-pipeline");
			foreach (var db in dbs)
			{
				_currentDb = db;
				_tables = await pipeline.ExecuteAsync(async ct =>
				{
					return await instanceService.GetTables(_selectedInstance, db, _selectedSite, _responseHeaders);
				});
				_totalCount = _tables.Count;
				_progress = 0;
				var sb = new StringBuilder(_tables.Count * 1000);
				string firstSql = string.Empty;
				foreach (var table in _tables)
				{
					var matched = _tableIndex.Match(table);
					if (matched.Success)
					{
						var tableIndex = int.Parse(matched.Groups[2].Value);
						if (tableIndex >= _tableCount)
						{
							_progress++;
							StateHasChanged();
							continue;
						}
						else
						{
							if (tableIndex == 0)
							{
								firstSql = string.Empty;
								var createSql = await pipeline.ExecuteAsync(async ct =>
								{
									return await instanceService.GetTableStructs(_selectedInstance, db, table, _selectedSite, _responseHeaders, _tables);
								}, CancellationToken.None);
								if (!string.IsNullOrWhiteSpace(createSql))
								{
									if (_progress != 0)
									{
										sb.Append(";");
										sb.Append(Environment.NewLine);
									}

									sb.Append(createSql);
									firstSql = createSql;
								}
							}
							else
							{
								var sql = firstSql.Replace($"{matched.Groups[1]}_0", $"{matched.Groups[1]}_{tableIndex}");
								if (_progress != 0)
								{
									sb.Append(";");
									sb.Append(Environment.NewLine);
								}

								sb.Append(sql);
							}
						}
					}
					else
					{
						firstSql = string.Empty;
						var createSql = await pipeline.ExecuteAsync(async ct =>
						{
							return await instanceService.GetTableStructs(_selectedInstance, db, table, _selectedSite, _responseHeaders, _tables);
						}, CancellationToken.None);
						if (!string.IsNullOrWhiteSpace(createSql))
						{
							if (_progress != 0)
							{
								sb.Append(";");
								sb.Append(Environment.NewLine);
							}

							sb.Append(createSql);
						}

						// await Task.Delay(1000);
					}
					_progress++;
					StateHasChanged();
				}
				sb.Append(";");
				var bytes = Encoding.UTF8.GetBytes(sb.ToString());
				var fileName = $"{db}.sql";

				await javaScript.InvokeVoidAsync("downloadFileFromBytes", bytes, fileName, "application/zip");
			}

		}
		catch (HttpRequestException httpEx)
		{
			// 专门捕获 HTTP 层异常，可能包含内部异常
			Console.WriteLine($"HTTP 请求异常: {httpEx.Message}");
			if (httpEx.InnerException != null)
			{
				Console.WriteLine($"内部异常: {httpEx.InnerException.Message}");
				// 这里可能会看到 "The credentials supplied to the package were not recognized"
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine($"发生错误: {ex.Message}");

		}
		finally
		{
			_processing = false;
		}
	}



	private void HandleLogin(LoginResponseDto response)
	{
		_selectedSite = response.SelectedSite;
		_responseHeaders = response.ResponseHeaders;
	}
}